/*
 * @Copyright: Citylife 2021
 * @Copyright: EasyCompany 2021
 * @Author: asterisk
 * @Date: 2021-03-15 15:20:41
 * @Description: 
 */
import 'package:flutter/foundation.dart';
import 'package:stack_trace/stack_trace.dart';

import '../easy_log.dart';
import 'utils.dart';

class EasyLogger {
  EasyLoggerConfig config;
  EasyLogger({this.config});

  void log(
      {String logName,
      String className,
      String functionName,
      int timestamp,
      EasyLogLevel level,
      dynamic error,
      StackTrace trace,
      @required Object message}) {
    if (level < config.logLevel) {
      return;
    }

    timestamp ??= fromMillisecondsSinceEpoch();

    if (null == className || null == functionName) {
      var list = Trace.current().frames[2].member.split(".");
      if (1 <= list.length) {
        className = list[0];
        if (2 <= list.length) {
          functionName = list[1];
        }
      }
    }
    var logMessage = EasyLogMessage(
        tags: {
          'logName': logName,
          'className': className,
          'functionName': functionName
        },
        timestamp: timestamp,
        level: level,
        error: error,
        trace: trace,
        message: message);
    config.appenders.forEach((appender) {
      appender.logo(logMessage);
    });
  }

  void logInfo(
      {@required String appName,
      @required List<int> version,
      @required DateTime date,
      EasyLogInfoType type}) {
    var logInfo =
        EasyLogInfo(name: appName, version: version, date: date, type: type);
    config.appenders.forEach((appender) {
      appender.logo(logInfo);
    });
  }

  void verbose(Object message,
          {String className,
          String functionName,
          int timestamp,
          dynamic error,
          StackTrace trace}) =>
      log(
          logName: config.logName,
          className: className,
          functionName: functionName,
          timestamp: timestamp,
          level: EasyLogLevel.VERBOSE,
          error: error,
          trace: trace,
          message: message);

  void debug(Object message,
          {String className,
          String functionName,
          int timestamp,
          dynamic error,
          StackTrace trace}) =>
      log(
          logName: config.logName,
          className: className,
          functionName: functionName,
          timestamp: timestamp,
          level: EasyLogLevel.DEBUG,
          error: error,
          trace: trace,
          message: message);

  void info(Object message,
          {String className,
          String functionName,
          int timestamp,
          dynamic error,
          StackTrace trace}) =>
      log(
          logName: config.logName,
          className: className,
          functionName: functionName,
          timestamp: timestamp,
          level: EasyLogLevel.INFO,
          error: error,
          trace: trace,
          message: message);
  void warning(Object message,
          {String className,
          String functionName,
          int timestamp,
          dynamic error,
          StackTrace trace}) =>
      log(
          logName: config.logName,
          className: className,
          functionName: functionName,
          timestamp: timestamp,
          level: EasyLogLevel.WARNING,
          error: error,
          trace: trace,
          message: message);

  void error(Object message,
          {String className,
          String functionName,
          int timestamp,
          dynamic error,
          StackTrace trace}) =>
      log(
          logName: config.logName,
          className: className,
          functionName: functionName,
          timestamp: timestamp,
          level: EasyLogLevel.ERROR,
          error: error,
          trace: trace,
          message: message);
  void fatal(Object message,
          {String className,
          String functionName,
          int timestamp,
          dynamic error,
          StackTrace trace}) =>
      log(
          logName: config.logName,
          className: className,
          functionName: functionName,
          timestamp: timestamp,
          level: EasyLogLevel.FATAL,
          error: error,
          trace: trace,
          message: message);

  void crash(Object message,
          {String className,
          String functionName,
          int timestamp,
          dynamic error,
          StackTrace trace}) =>
      log(
          logName: config.logName,
          className: className,
          functionName: functionName,
          timestamp: timestamp,
          level: EasyLogLevel.CRASH,
          error: error,
          trace: trace,
          message: message);

  void head() {
    logInfo(
        appName: EasyLoggerFactory.appName,
        version: EasyLoggerFactory.appVersion,
        date: EasyLoggerFactory.appDate,
        type: EasyLogInfoType.head);
  }

  void foot() {
    logInfo(
        appName: '',
        version: [],
        date: DateTime.now(),
        type: EasyLogInfoType.foot);
  }

  void dispose() {
    foot();
  }
}
